from fastapi.exceptions import RequestValidationError
from typing import Optional
from fastapi import FastAPI, File, UploadFile, Request, status,Header
from fastapi.staticfiles import StaticFiles
from fastapi.responses import JSONResponse
from fastapi.encoders import jsonable_encoder
import os.path
from starlette.responses import FileResponse
import csv
from fastapi.middleware.cors import CORSMiddleware
# from http import server
import time
import datetime
import json
from tkinter import messagebox

# 使用微信接口给微信好友发送消息，
import itchat
from pydantic import BaseModel
import re
from fastapi.responses import RedirectResponse
from starlette.templating import Jinja2Templates


# # 微信信息的方法注釋掉了。

# # 自动登录方法，hotReload=True可以缓存，不用每次都登录,但是第一次执行时会出现一个二维码，需要手机微信扫码登录
# itchat.auto_login(hotReload=False)

# # 搜索好友，search_friends("xxx"),其中"xxx"为好友昵称，备注或微信号不行
# userfinfo = itchat.search_friends("辣白菜")# "智能群管家014"为好友昵称
# print("userfinfo:",userfinfo)
# # print(userfinfo)，获取userinfo中的UserName参数
# userid = userfinfo[0]["UserName"]# 获取用户id


# def send_msg(msg):
#     # 调用微信接口发送消息
#     # itchat.send("",userid)# 通过用户id发送信息
#     # 或
#     itchat.send_msg(msg=msg, toUserName=userid)# 发送纯文本信息


app = FastAPI()
origins = [
    "http://api.zwnsyw.com",
    "https://api.zwnsyw.com",
    "http://localhost",
    "http://localhost:3000",
    "http://192.168.1.254:3000"
]
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
app.mount("/material", StaticFiles(directory="./material"), name="/material")

tmp = Jinja2Templates(directory='templates')


# download stu job
@app.get("/file/{filenameq}")
def file(filenameq: str):
    return FileResponse("./student/a/{}".format(filenameq), filename=filenameq)

# download material 
@app.get("/filematerial/{filenameq}")
def file_material(filenameq: str):
    return FileResponse("./introduce/{}".format(filenameq), filename=filenameq)

@app.get("/listdir")
def listdir():
    return os.listdir("./material")

# @app.post("/")
# def read_root():
#     return {"Hello": "World"}
def get_date():
    # begin = datetime.date(2014,6,1)
    end = datetime.date()
    data_list = []
    for i in range(7):
        day = end - datetime.timedelta(days=i)
        data_list.append(day)
    return data_list

# list image 
@app.get("/listf")
async def getfile():
    # ti = [  os.path.getmtime(os.path.join('./student/a', f)) for f in file_list]
    # Get all regular files
    with open('./today.json', 'r',encoding='utf8') as myfile:
        data=myfile.read()
    # parse file
    today = json.loads(data)
    today['today'] 
    file_list = [
        name
        for name in os.listdir("./material/{}/".format( today['today']))
        if os.path.isfile(os.path.join("./material/{}/".format( today['today']), name))
    ]
    return {"file_list": ["/material/{}/".format( today['today']) + e for e in file_list]}

# list student 
@app.get("/liststuf")
async def getstufile():
    # Get all regular files
    file_list = [
        name
        for name in os.listdir("./student/a")
        if os.path.isfile(os.path.join("./student/a", name))
    ]
    ti = [os.path.getmtime(os.path.join("./student/a", f)) for f in file_list]
    print(ti, 888)
    aa = [time.strftime("%Y-%m-%d", time.localtime(t)) for t in ti]
    print(aa)
    # [{'fl':a,'tl':b}for a,b in  zip(file_list,ti)]
    return {"file_list": [{"fl": a, "tl": b} for a, b in zip(file_list, aa)]}

# list c
@app.get("/listf/{namef}")
async def getstuffile(namef: str):
    file_list = [
        name
        for name in os.listdir("./material/{}/".format( namef))
        if os.path.isfile(os.path.join("./material/{}/".format( namef), name))
    ]
    return {"file_list": ["/material/{}/".format( namef) + e for e in file_list]}
# list pdf 
@app.get("/listpdf")
async def getpdffile():
    # Get all regular files
    file_list = [
        name
        for name in os.listdir("./introduce")
        if os.path.isfile(os.path.join("./introduce", name))
    ]
    ti = [os.path.getmtime(os.path.join("./introduce", f)) for f in file_list]
    print(ti, 888)
    aa = [time.strftime("%Y-%m-%d", time.localtime(t)) for t in ti]
    print(aa)
    # [{'fl':a,'tl':b}for a,b in  zip(file_list,ti)]
    return {"file_list": [{"fl": a, "tl": b} for a, b in zip(file_list, aa)]}

# upload file
@app.post("/uploadFile")
async def uploadFile(request: Request, file: UploadFile = File(...)):
    print(file.filename)
    if file.filename.split(".")[1] != "pptx":
        return False
    """缺少验证是否上传文件"""
    content = await file.read()
    client_host = request.client.host

    # print(content)
    with open("./student/a/{}".format(client_host+'_'+file.filename), "wb") as f:
        f.write(content)

    data = {
        "ip": client_host,
        "filename": file.filename,
        "time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
    }

    # data2 = json.dumps(data)
    # print(data2)
    file_name = "list.json"
    with open(file_name, "a+") as f:
        # 写入方式1，等价于下面这行
        json.dump(data, f, ensure_ascii=False)
    with open("list.csv", "a+", newline="", encoding="utf-8") as myFile:
        myWriter = csv.writer(myFile)
        # writerrow一行一行写入
        # myWriter.writerow([client_host,8,9])
        myWriter.writerow(
            [client_host, file.filename, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")]
        )
        # writerow多行写入
        # myList=[[1,2,3],[4,5,6]]
        # myWriter.writerows(myList)
    return {"filename": file.filename}

@app.post("/uploadComment")
async def uploadComment(request: Request, file: UploadFile = File(...)):

    # print(file.filename)
    # if file.filename.split(".")[1] != "pptx":
    #     return False
    """缺少验证是否上传文件"""
    content = await file.read()
    # print(content)
    with open("./student/b/{}".format(file.filename), "wb") as f:
        f.write(content)
    client_host = request.client.host

    data = {
        "ip": client_host,
        "filename": file.filename,
        "time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        # "content":content.decode('utf8')
    }

    messagebox.showinfo(data)


    # data2 = json.dumps(data)
    # print(data2)
    file_name = "comment.json"
    with open(file_name, "a+") as f:
        # 写入方式1，等价于下面这行
        json.dump(data, f, ensure_ascii=False)
    with open("comment.csv", "a+", newline="", encoding="utf-8") as myFile:
        myWriter = csv.writer(myFile)
        # writerrow一行一行写入
        # myWriter.writerow([client_host,8,9])
        myWriter.writerow(
            [client_host, file.filename, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")]
        )
        # writerow多行写入
        # myList=[[1,2,3],[4,5,6]]
        # myWriter.writerows(myList)
    return {"filename": file.filename}


class Item(BaseModel):
    name: str
    region: str
    type: str
@app.post("/uploadidea")
async def uploadA(item: Item):
    with open("comments.csv", "a+", newline="", encoding="utf-8") as myFile:
        myWriter = csv.writer(myFile)
        # writerrow一行一行写入
        # myWriter.writerow([client_host,8,9])
        myWriter.writerow(
            [item.name, item.region, item.type]
        )
    
# upload commit 
@app.post("/uploadcommit")
async def uploadCommit(request: Request, file: UploadFile = File(...)):
    if file.filename.split(".")[1] != "docx":
        return False
    # print(file.filename)
    # if file.filename.split(".")[1] != "pptx":
    #     return False
    """缺少验证是否上传文件"""
    content = await file.read()
    # print(content)
    with open("./student/c/{}".format(file.filename), "wb") as f:
        f.write(content)
    client_host = request.client.host

    data = {
        "ip": client_host,
        "filename": file.filename,
        "time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        # "content":content.decode('utf8')
    }

    messagebox.showinfo(data)


    # data2 = json.dumps(data)
    # print(data2)
    file_name = "commit.json"
    with open(file_name, "a+") as f:
        # 写入方式1，等价于下面这行
        json.dump(data, f, ensure_ascii=False)
    with open("commit.csv", "a+", newline="", encoding="utf-8") as myFile:
        myWriter = csv.writer(myFile)
        # writerrow一行一行写入
        # myWriter.writerow([client_host,8,9])
        myWriter.writerow(
            [client_host, file.filename, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")]
        )
        # writerow多行写入
        # myList=[[1,2,3],[4,5,6]]
        # myWriter.writerows(myList)
    return {"filename": file.filename}

@app.get("/gameauth")
async def authgame(request: Request):
    with open('./today.json', 'r',encoding='utf8') as myfile:
        data=myfile.read()
    # parse file
    flag_f = json.loads(data)
    with open('./auth.json', 'r',encoding='gbk') as myfile:
        data=myfile.read()
    # parse file
    ip_list = json.loads(data)
    client_host = request.client.host
    flag_ = flag_f['flag']
    
    if str(client_host) in ip_list:
        flag_ = True
    return flag_
# authrized game
@app.get("/gamestart/{stu_ip}")
async def autgamestart(stu_ip: str,request:Request):
    if request.client.host != '127.0.0.1':
        return '少年你想多了！'
    with open('./auth.json', 'r',encoding='gbk') as myfile:
        data=myfile.read()

    # parse file
    lis = json.loads(data)
    lis.append(stu_ip.split('_')[0])

    with open('./auth.json', 'w',encoding='gbk') as outfile:
        json.dump(lis, outfile,ensure_ascii=False)
    return '少年你这么优秀！你家里人知道么！'
# shwo button
@app.get("/showbutton")
async def showbutton(request: Request):
    ip_list = [
        "127.0.0.1",
        # # "192.168.1.55",
        # # "192.168.1.43",
        # # "192.168.1.57",
        # # "192.168.1.73",
        # "192.168.1.55",
        # "192.168.1.65",
        # # "192.168.1.85",
        # "192.168.1.69",
        # "192.168.1.43",
        # # "192.168.1.88",
        # "192.168.1.84",
        # "192.168.1.74",
        # # "192.168.1.85",
        # "192.168.1.73",
    ]
    client_host = request.client.host
    flag_ = False
    if str(client_host) in ip_list:
        flag_ = True
    return flag_

@app.get("/listrecord")
async def authgame(request: Request):
    with open('./record.json', 'r',encoding='utf8') as myfile:
        data=myfile.read()
    # parse file
    record_list = json.loads(data)
    for e in record_list:
        start_c= len(e['student'])-1
        print(start_c,e['student'],111)
        namearr = [e for e in e['student']]
        for i in range(start_c):
           namearr[-1*(i+1)] = '*'
        e['student_'] = ''.join(namearr)
    return record_list

@app.get("/sendfeedback/{feedback}")
async def sendfeed(feedback: str,request: Request):
    send_msg(feedback)

@app.get("/topic")
async def gettopic(request: Request):
    with open('./today.json', 'r',encoding='utf8') as myfile:
        data=myfile.read()
    # parse file
    today = json.loads(data)
    print(today,555)
    return today

@app.get("/time")
async def gettopic(request: Request):
    
    return time.localtime(time.time())
# tackle with cheating 
@app.get("/cheating")
async def gettopic(request: Request):
    return tmp.TemplateResponse('index.html',
                                {'request':request,  # 一定要返回request
                                 'args':'hello world'  # 额外的参数可有可无
                                 }
                                )
    # return 'GUN'

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    response = await call_next(request)
    
    # print(len(re.findall('games',str(request.url))),999)
    if len(re.findall('games',str(request.url)))>0:
        with open('./auth.json', 'r',encoding='gbk') as myfile:
            data=myfile.read()
        # parse file
        ip_list = json.loads(data)
        client_host = request.client.host
        if str(client_host) in ip_list:
            return response
        else:
            return RedirectResponse("http://192.168.1.254:9000/cheating") 


    return response 


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=9000)
# 